經過前幾天的努力,總算是把功能寫完也成功啟動服務了,但在確認功能正常之前,說完成好像也還太早了。
俗話說的好:不出意外的話,就要出意外了 XD
所以,今天我們就來實際測試一下 API ,看看是否如我們預期般運作吧!
今天選用的工具不是常用的 Postman,選擇這個工具單純只是操作簡單,也足以滿足目前使用的需求,且由於並非專業QA,本篇文章僅簡單的規劃幾個場景進行測試。
那我們就開始進入今天的正題!
我用的是 Ghrome 的 Extension 「Talend API Tester」,只要在瀏覽器加入此擴充功能即可使用,非常方便。下方是官方提供介面截圖,介面相當簡潔,左側可以為專案、服務建立資料夾,分門別類存放欲測試的API。右側上方可選擇Http Method、Header 想包含的資訊與 Request Body。下方則顯示 API 的 Response資訊。
圖片來源:Talend API Tester
以下以註冊用戶為例說明建立 Request 的過程:
新增一個 Project:點擊 MY DRIVE 旁的設定鈕,選擇 Add a project,輸入專案名稱。
新增一個 Service:點擊剛剛新增的專案旁的設定鈕,選擇Add a service,我習慣以 CRUD 來分類,因此此處我輸入 Create 作為 folder 名稱
新增一個 Request:點擊剛剛新增的 service旁的設定鈕,選擇 Add a request,輸入本次請求名稱,我習慣對應 Controller 中的方法名稱,因此這邊命名為 registerUser
設定 request 內容:在我們剛新增的Request中設定以下內。
Method: POST
URL: http://localhost:8081/users
Body: 選擇 JSON
格式,並貼上以下內容:JSON
{ "email": "test@example.com", "password": "password123" }
至此,我們就成功地在 API Tester 中為註冊用戶的 API 建立了一個 Request。
記得點擊畫面右上方的 Save ,讓我們在未來每次使用不用重複輸入這些資訊。
這個環節我們使用上面建立好的 Request 進行測試。
會有 正向測試 (也就是成功註冊的場景),以及 反向測試(故意測試不應成功的場景,例如重複 email 或參數格式不正確。)
預期應該會收到一個 201 Created
的 HTTP 狀態碼,回應內容為空,代表使用者已成功建立。
成功建立後,我們可以連線到db看看是否成功儲存。輸入以下指令在終端機查看資料庫內容:
# 在已經運行的 postgre 容器中啟動 bash 以便輸入指令
docker-compose exec postgres bash
#連線資料庫
psql -U your_username -d auth_db
#成功連線後會看到auth_db=#,輸入查詢指令
SELECT * FROM users;
結果如下,註冊的帳號如期出現,密碼也經加密後儲存:
再次發送與上次完全相同的請求,這次我們預期會收到 400 Bad Request
的錯誤,回應內容會是我們在 Service 中設定的錯誤訊息:「Error: Email is already in use!」。
這次我們想針對在 Dto 加上的檢核進行測試,嘗試發送一個密碼少於 8 個字元的請求,預期會收到 400 Bad Request
的錯誤,且回應內容應是我們在 Dto 中設定的訊息 "Password must be between 8 and 20 characters"
。
這裡出了一點小問題,這次的回應不如我們的預期,回傳了 403 Forbidden。
在測試三嘗試輸入違反長度限制的密碼時,Response 一開始並沒有如預期回覆 400 Bad Request,而是回覆了 403 Forbidden,因此這個章節要來追蹤哪個環節出了問題。
首先,在 application.properties 中開啟 debug 模式:
logging.level.org.springframework.security=DEBUG
重啟docker-compose的服務,並再次發出密碼長度不符的請求。
此時查看 service log ,應該會發現某些關鍵的錯誤訊息,透過以下這些訊息,我們可以逐步了解服務出了什麼問題:
請求進入,驗證失敗
POST /users
請求成功進入服務。但因為密碼欄位驗證失敗,Spring 拋出了 MethodArgumentNotValidException
,到此為止,一切都符合預期。... [nio-8081-exec-1] o.s.security.web.FilterChainProxy : Secured POST /users
... [nio-8081-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: ...
Spring 試圖處理錯誤
MethodArgumentNotValidException
進行處理,Spring 的預設錯誤處理機制 DefaultHandlerExceptionResolver
接管了這個未被捕捉的Exception。DefaultHandlerExceptionResolver
的預設行為會將請求轉發到 Spring Boot 預設的錯誤頁面,也就是 /error
這個路徑。Spring Security 攔截了/error
請求
/error
路徑的請求,重新用我們設定的安全規則來審查這個新請求。2025-09-23T11:09:55.895197009Z 2025-09-23T11:09:55.894Z DEBUG 1 --- [nio-8081-exec-1] o.s.security.web.FilterChainProxy : Securing POST /error
結論:安全規則判斷牴觸
/users/**
的路徑權限,因此存取被拒,回傳 403。2025-09-23T11:09:55.914938279Z 2025-09-23T11:09:55.914Z DEBUG 1 --- [nio-8081-exec-1] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access
今天,我們認識了 API 測試工具,設計了測試場景,並透過反向測試發現了一個意料之外的問題。在逐步釐清問題發生的原因之後,明天我們想透過自訂Exception來解決這個問題。